package com.example.hissys.service;

import com.example.hissys.dto.AppointmentDetailDTO;
import com.example.hissys.dto.AppointmentRequest;
import com.example.hissys.entity.Appointment;
import com.example.hissys.entity.DoctorSchedule;
import com.example.hissys.mapper.AppointmentMapper;
import com.example.hissys.mapper.ScheduleMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
import java.util.Map;
import java.util.HashMap;

@Service
@Slf4j
public class AppointmentService {
    @Autowired
    private AppointmentMapper appointmentMapper;
    
    @Autowired
    private ScheduleMapper scheduleMapper;

    /**
     * 创建预约
     */
    @Transactional
    public Map<String, Object> createAppointment(AppointmentRequest request) {
        log.info("Creating appointment for user: {} with doctor: {} on date: {} time: {}", 
            request.getUserId(), 
            request.getDoctorId(),
            request.getAppointmentDate(), 
            request.getAppointmentTime());

        // 检查该用户在同一天同一时间段是否已有预约
        int count = appointmentMapper.checkExistingAppointment(
            request.getUserId(),
            request.getDoctorId(),  // 添加医生ID
            request.getAppointmentDate(),
            request.getAppointmentTime()
        );
        
        if (count > 0) {
            log.error("User {} already has an unpaid appointment with doctor {} on {} at {}", 
                request.getUserId(), 
                request.getDoctorId(),
                request.getAppointmentDate(), 
                request.getAppointmentTime());
            throw new RuntimeException("您已在该医生的该时间段有未支付的预约");
        }

        // 2. 检查排班是否存在且有号源
        DoctorSchedule schedule = scheduleMapper.checkAvailability(
            request.getDoctorId(),
            request.getAppointmentDate(),
            request.getAppointmentTime()
        );
        if (schedule == null) {
            throw new RuntimeException("该时段已约满");
        }

        // 3. 更新号源数量
        int updated = scheduleMapper.updateAvailableSlots(
            request.getDoctorId(),
            request.getAppointmentDate(),
            request.getAppointmentTime()
        );
        if (updated == 0) {
            throw new RuntimeException("预约失败，请重试");
        }

        // 4. 创建预约记录
        Appointment appointment = new Appointment();
        appointment.setUserId(request.getUserId());
        appointment.setDoctorId(request.getDoctorId());
        appointment.setAppointmentDate(java.sql.Date.valueOf(request.getAppointmentDate()));
        appointment.setAppointmentTime(request.getAppointmentTime());
        appointment.setStatus("pending");
        appointment.setPaymentStatus("unpaid");

        appointmentMapper.create(appointment);

        // 预约成功后，获取更新后的排班信息
        List<DoctorSchedule> updatedSchedules = scheduleMapper.findByDoctorIdAndDate(
            request.getDoctorId(),
            request.getAppointmentDate()
        );
        
        log.info("Updated schedules for doctor {} on {}: {}", 
                request.getDoctorId(), 
                request.getAppointmentDate(), 
                updatedSchedules);

        // 返回预约信息和更新后的排班信息
        Map<String, Object> result = new HashMap<>();
        result.put("appointment", appointment);
        result.put("schedules", updatedSchedules);
        return result;
    }

    /**
     * 获取用户预约列表
     */
    public List<AppointmentDetailDTO> getAppointmentList(Integer userId) {
        log.info("Getting appointment list for user: {}", userId);
        return appointmentMapper.findByUserId(userId);
    }

    /**
     * 取消预约
     */
    @Transactional
    public void cancelAppointment(Integer appointmentId) {
        log.info("Cancelling appointment with ID: {}", appointmentId);
        
        int deleted = appointmentMapper.cancelAppointment(appointmentId);
        if (deleted == 0) {
            throw new RuntimeException("取消预约失败，预约可能不存在");
        }
        
        log.info("Successfully cancelled appointment {}", appointmentId);
    }

    /**
     * 支付预约
     */
    @Transactional
    public void payAppointment(Integer appointmentId) {
        log.info("Paying for appointment: {}", appointmentId);
        
        int updated = appointmentMapper.payAppointment(appointmentId);
        if (updated == 0) {
            throw new RuntimeException("支付失败，可能已支付或已取消");
        }
    }
} 